import csv

import models
import forms
import hooks

from django.http import HttpResponse
from django.template import Context, loader
from django.shortcuts import render_to_response, get_object_or_404
from django.contrib import auth
from django import http
from django.core.files.base import ContentFile

def login(request):
    if request.method == "POST":
        form = forms.LoginForm(request.POST)
        if form.is_valid():
            user = auth.authenticate(username=form.cleaned_data['username'], 
                    password=form.cleaned_data['password'])
            auth.login(request, user)
            return http.HttpResponseRedirect("../home")
    else:
        form = forms.LoginForm()
    return render_to_response("grading/form.html",
            {
                "user": request.user,
                "form": form
                }
            )

def logout(request):
    if not request.user.is_authenticated():
        return http.HttpResponseRedirect("../login")
    auth.logout(request)
    return render_to_response("grading/message.html",
            {
                "user": request.user,
                "message": "you are now logged out"
                })

def home(request):
    if not request.user.is_authenticated():
        return http.HttpResponseRedirect("../login")
    hometest = models.Submissions.objects.order_by('assignment')
    if models.UserProfile.objects.get(user=request.user).type == "Professor":
        return render_to_response("grading/prof_home.html",
                {"user": request.user})
    userlist = models.User.objects.all()
    return render_to_response('grading/home.html',
            {
                "user": request.user,
                'userlist': userlist,
                })
 

def tograde(request):
    if not request.user.is_authenticated():
        return http.HttpResponseRedirect("../login")
    toGrade = [i for i in models.Grades.objects.filter(user=request.user) if 
            i.grade == -1]
    return render_to_response("grading/tograde.html",
            {
                "user": request.user,
                "tograde": toGrade
                })



def grade(request, id):
    if not request.user.is_authenticated():
        return http.HttpResponseRedirect("../login")
    try:
        toGrade = models.Grades.objects.all().filter(
                submission__pk=id).filter(user=request.user)[0]
    except IndexError:
        raise http.Http404

    if toGrade.grade != -1:
        return render_to_response("grading/message.html",
                {
                    "user": request.user,
                    "message": "You have already graded this submission"
                    })

    if request.method == "POST":
        gradeForm = forms.GradeForm(request.POST)
        if gradeForm.is_valid():
            toGrade.grade = gradeForm.cleaned_data["grade"]
            toGrade.comments = gradeForm.cleaned_data["comments"]
            toGrade.save()
            hooks.calculate(toGrade.submission)
            return http.HttpResponseRedirect("../../tograde")
    else:
        gradeForm = forms.GradeForm()

    return render_to_response("grading/grade.html",
            {
                "user": request.user,
                "tograde": toGrade,
                "form": gradeForm
                })

def viewgrades(request):
    if not request.user.is_authenticated():
        return http.HttpResponseRedirect("../login")
    grades = [ i for i in models.Submissions.objects.filter(
            student=request.user) if i.finalGrade != -1]

    return render_to_response("grading/viewgrades.html",
            {
                "user": request.user,
                "grades": grades,
                "student": request.user
                })

def viewgrade(request, id):
    if not request.user.is_authenticated():
        return http.HttpResponseRedirect("../login")
    try:
        to_show = models.Submissions.objects.filter(
                assignment__pk=id).filter(student=request.user)[0]
    except IndexError:
        raise http.Http404

    grades = models.Grades.objects.filter(
            submission__student=request.user).filter(
            submission__assignment__pk=id)

    return render_to_response("grading/viewgrade.html",
            {
                "user": request.user,
                "to_show": to_show,
                "grades": grades,
                }
            )

def viewassignments(request):
    if not request.user.is_authenticated():
        return http.HttpResponseRedirect("../login")

    toSubmit = [i for i in models.Assignments.objects.all() if 
            len(models.Submissions.objects.all().filter(
                assignment=i.pk).filter(student=request.user)) == 0]

    return render_to_response("grading/viewassignments.html",
            {
                "user": request.user,
                "tosubmit": toSubmit
                })

def submit(request, id):
    if not request.user.is_authenticated():
        return http.HttpResponseRedirect("../login")
    toSubmit=get_object_or_404(models.Assignments, pk=id)
    if len(models.Submissions.objects.filter(
        student=request.user).filter(assignment=toSubmit)) != 0:
        return render_to_response("grading/message.html",
                {
                    "user": request.user,
                    "message": "you have already turned in this assignment"
                    })

    if request.method == "POST":
        submitForm = forms.SubmitForm(request.POST, request.FILES)
        if submitForm.is_valid():
            
            s = models.Submissions(
                    assignment=toSubmit,
                    student=request.user,
                    selfGrade=submitForm.cleaned_data["grade"],
                    finalGrade=-1)
            s.file.save(
                        request.FILES["file"].name, 
                        ContentFile(request.FILES["file"].read())
                        )
            s.save()
            hooks.distribute_submissions(toSubmit)
            return http.HttpResponseRedirect("../../viewassignments")

    else:
        submitForm = forms.SubmitForm()

    return render_to_response("grading/submit.html",
            {
                "user": request.user,
                "assignment": toSubmit,
                "form": submitForm
                })

#Professor only
def grades_csv(request, id):
    if not request.user.is_authenticated():
        return http.HttpResponseRedirect("../login")
    hooks.check_prof(request.user)
    assignment = get_object_or_404(models.Assignments, pk=id)

    response = HttpResponse(mimetype='text/csv')
    response['Content-Disposition' ] = 'attachment; filename=%s-grades.csv' % (
            assignment.name,)
    writer = csv.writer(response)
    writer.writerow(['User', 'Grade'])
    subs = [i for i in models.Submissions.objects.filter(assignment=assignment) 
            if i.finalGrade != -1]
    for sub in subs:
        writer.writerow([sub.student, sub.finalGrade])
    return response

def download_grades(request):
    if not request.user.is_authenticated():
        return http.HttpResponseRedirect("../login")
    hooks.check_prof(request.user)
    return render_to_response("grading/download_grades.html",
            {
                "user": request.user,
                "assignments": models.Assignments.objects.all()
                })


def create_user(request):
    if not request.user.is_authenticated():
        return http.HttpResponseRedirect("../login")
    hooks.check_prof(request.user)

    if request.method == "POST":
        form = forms.NewUserForm(request.POST)
        if form.is_valid():
            user = auth.models.User.objects.create_user(
                    form.cleaned_data["username"],
                    "",
                    form.cleaned_data["password"]
                    )
            type = form.cleaned_data["type"]
            user.is_staff = type == "Professor"
            user.save()
            ranking = {
                    "Professor": 10,
                    "TA": 7,
                    "Student": 1
                    }[type]
            profile = models.UserProfile(user=user, type=type, ranking=ranking)
            profile.save()
            return http.HttpResponseRedirect("../home/")
    else:
        form = forms.NewUserForm()
    return render_to_response("grading/form.html",
            {
                "user": request.user,
                "form": form
                })

def create_assignment(request):
    if not request.user.is_authenticated():
        return http.HttpResponseRedirect("../login")
    hooks.check_prof(request.user)

    if request.method == "POST":
        form = forms.NewAssignmentForm(request.POST)
        if form.is_valid():
            assignment = models.Assignments(
                    name=form.cleaned_data["name"],
                    description=form.cleaned_data["description"]
                    )
            assignment.save()
            return http.HttpResponseRedirect("../home/")
    else:
        form = forms.NewAssignmentForm()
    return render_to_response("grading/form.html",
            {
                "user": request.user,
                "form": form
                })
